//+------------------------------------------------------------------+
//|                        ChartObjectPanel.mqh                       |
//|                   Copyright 2000-2025, MetaQuotes Ltd.            |
//|                            https://www.mql5.com                  |
//+------------------------------------------------------------------+
#include <ChartObjects/ChartObjectsTxtControls.h>  // 引入文本控件基类（如CChartObjectButton、CChartObjectLabel）
#include <Arrays/ArrayObj.h>                       // 引入对象数组类（管理动态对象集合）
#include <Arrays/ArrayInt.h>                       // 引入整数数组类（存储偏移量等整数数据）

//+------------------------------------------------------------------+
//| CChartObjectPanel 类                                              |
//| 功能：图表对象面板类，继承自按钮类，用于分组管理图表上的关联对象   |
//| 核心特性：                                                       |
//|  1. 子对象管理：支持附加标签类子对象（CChartObjectLabel），统一管理位置与可见性 |
//|  2. 展开/折叠控制：通过状态切换显示/隐藏子对象，节省图表空间        |
//|  3. 位置联动：面板移动时，所有子对象自动跟随偏移，保持相对位置不变  |
//|  4. 尺寸自适应：展开时自动计算面板尺寸以容纳所有子对象，折叠时收缩  |
//| 继承关系：public CChartObjectButton（基于按钮类，支持点击交互触发状态切换） |
//+------------------------------------------------------------------+
class CChartObjectPanel : public CChartObjectButton
  {
protected:
   CArrayObj         m_attachment;       // 附加子对象数组（存储CChartObjectLabel类型的子对象，由面板统一管理）
   CArrayInt         m_dX;               // 子对象X偏移量数组（存储每个子对象相对于面板的X方向偏移，用于位置联动）
   CArrayInt         m_dY;               // 子对象Y偏移量数组（存储每个子对象相对于面板的Y方向偏移，用于位置联动）
   bool              m_expanded;         // 展开/折叠状态标志（true=展开，显示所有子对象；false=折叠，隐藏子对象）

public:
   /**
    * @brief 构造函数：初始化图表对象面板
    * @details 调用父类CChartObjectButton构造函数，初始化子对象数组，默认设置为展开状态（m_expanded=true）
    */
                     CChartObjectPanel();

   /**
    * @brief 析构函数：销毁图表对象面板
    * @details 自动释放m_attachment数组中管理的所有子对象（无需手动删除），避免资源泄漏
    */
                    ~CChartObjectPanel();

   //--- 子对象附加接口
   /**
    * @brief 向面板附加标签类子对象（CChartObjectLabel）
    * @param chart_object [in] 待附加的标签对象（需提前创建，面板将接管其位置与可见性管理）
    * @return bool - 操作结果：true表示附加成功，false表示失败（如对象为空或数组添加失败）
    * @note 附加后，子对象的位置将基于面板位置+偏移量自动计算，与面板保持联动
    */
   bool              Attach(CChartObjectLabel *chart_object);

   //--- X方向位置与偏移接口
   /**
    * @brief 设置面板的X方向偏移（相对于图表左上角），并联动更新所有子对象的X位置
    * @param X [in] 新的X方向偏移值（像素）
    * @return bool - 操作结果：true表示设置成功，false表示失败（如父类方法调用失败）
    * @note 子对象X位置 = 面板X偏移 + 对应m_dX数组中的偏移值
    */
   bool              X_Distance(const int X);

   /**
    * @brief 获取面板的X方向偏移（相对于图表左上角）
    * @return int - X方向偏移值（像素），复用父类CChartObjectButton的实现
    */
   int               X_Distance(void) const { return(CChartObjectButton::X_Distance()); }

   //--- Y方向位置与偏移接口
   /**
    * @brief 设置面板的Y方向偏移（相对于图表左上角），并联动更新所有子对象的Y位置
    * @param Y [in] 新的Y方向偏移值（像素）
    * @return bool - 操作结果：true表示设置成功，false表示失败（如父类方法调用失败）
    * @note 子对象Y位置 = 面板Y偏移 + 对应m_dY数组中的偏移值
    */
   bool              Y_Distance(const int Y);

   /**
    * @brief 获取面板的Y方向偏移（相对于图表左上角）
    * @return int - Y方向偏移值（像素），复用父类CChartObjectButton的实现
    */
   int               Y_Distance(void) const { return(CChartObjectButton::Y_Distance()); }

   //--- 面板宽度接口
   /**
    * @brief 计算面板当前宽度（根据展开/折叠状态动态调整）
    * @return int - 面板宽度（像素）：展开时为容纳所有子对象的最大宽度，折叠时为按钮自身宽度+边距
    */
   int               X_Size() const;

   /**
    * @brief （重载）获取指定Y位置的面板宽度（复用父类实现，通常用于特殊布局计算）
    * @param Y [in] Y位置（像素，未实际使用，仅保持接口兼容）
    * @return int - 面板宽度（像素），复用父类CChartObjectButton的实现
    */
   int               X_Size(const int Y) const { return(CChartObjectButton::X_Size()); }

   //--- 面板高度接口
   /**
    * @brief 计算面板当前高度（根据展开/折叠状态动态调整）
    * @return int - 面板高度（像素）：展开时为容纳所有子对象的最大高度，折叠时为按钮自身高度+边距
    */
   int               Y_Size() const;

   /**
    * @brief （重载）获取指定Y位置的面板高度（复用父类实现，通常用于特殊布局计算）
    * @param Y [in] Y位置（像素，未实际使用，仅保持接口兼容）
    * @return int - 面板高度（像素），复用父类CChartObjectButton的实现
    */
   int               Y_Size(const int Y) const { return(CChartObjectButton::Y_Size()); }

   //--- 时间周期可见性接口
   /**
    * @brief 获取面板的可见时间周期掩码（复用父类实现）
    * @return int - 时间周期掩码（位掩码，控制在哪些K线周期显示，如PERIOD_H1表示1小时周期）
    */
   int               Timeframes(void) const { return(CChartObjectButton::Timeframes()); }

   /**
    * @brief 设置面板及子对象的可见时间周期掩码
    * @param timeframes [in] 新的时间周期掩码（如PERIOD_H1 | PERIOD_H4表示在1小时和4小时周期显示）
    * @return bool - 操作结果：true表示设置成功，false表示失败（如父类或子对象设置失败）
    * @note 仅当面板处于展开状态时，子对象的可见周期才会同步更新
    */
   virtual bool      Timeframes(const int timeframes);

   //--- 展开/折叠状态接口
   /**
    * @brief 设置面板的展开/折叠状态，并同步更新子对象的显示状态
    * @param state [in] 新状态（true=展开，显示子对象；false=折叠，隐藏子对象）
    * @return bool - 操作结果：true表示状态设置成功，false表示失败（如父类状态设置失败）
    */
   bool              State(const bool state);

   /**
    * @brief 获取面板当前的展开/折叠状态
    * @return bool - 状态值（true=展开，false=折叠），复用父类CChartObjectButton的实现
    */
   bool              State(void) const  { return(CChartObjectButton::State()); }

   /**
    * @brief 检查并同步面板状态与子对象可见性（状态变化时触发）
    * @return bool - 操作结果：true表示状态发生变化并已同步，false表示状态未变化
    * @note 若面板实际状态（m_expanded）与父类记录的状态不一致，会更新m_expanded并调整子对象可见性
    */
   bool              CheckState();

protected:
  };
//+------------------------------------------------------------------+